
import keyi
import time

class KeYiTest:
  secretId:str
  secretKey:str
  projectId:int
  session:keyi.Session
  def __init__(self,secretId:str,secretKey:str,projectId:int):
    self.secretId = secretId
    self.secretKey = secretKey
    self.projectId = projectId

  def simple(self,keyCode:str,machineId:str):
    print("开始一个简单的测试，通常我们就这样使用这个sdk")
    print("1. 登录")
    session = keyi.Session(self.secretId,self.secretKey,self.projectId)
    login_result = session.login(keyCode,machineId)
    assert login_result,f"登录失败: {session.errorCode}"
    print("登录成功！")
    print(f"软件的数据: {session.data}")
    print(f"软件的公告: {session.notice}")
    print("2. 开始使用心跳，维持会话，通常tick的间隔时间在10秒-3分钟之间，如果间隔时间太短，会话可能会被服务器拉黑，如果间隔时间太长，会话可能会断开，需要重新登录")
    for i in range(3):
      tick_result = session.tick()
      assert tick_result,f"心跳失败: {session.errorCode}"
      time.sleep(2)
      print(f"心跳 {i+1}/3")
    print("3. 注销")
    logout_result = session.logout()
    assert logout_result,f"注销失败: {session.errorCode}"
    print("注销成功！")
    print("测试完成")

  def test_device_limit(self,keyCode:str,machineId:str):
    print("开始测试卡密的设备限制，确保keyCode是只支持单设备登录的卡密")
    print("1. 登录设备1")
    session = keyi.Session(self.secretId,self.secretKey,self.projectId)
    login_result = session.login(keyCode,machineId)
    assert login_result,f"登录失败: {session.errorCode}"
    print("登录成功！")
    print("2. 登录设备2")
    session2 = keyi.Session(self.secretId,self.secretKey,self.projectId)
    login_result = session2.login(keyCode,machineId)
    assert login_result,f"登录失败: {session2.errorCode}"
    print("登录成功！")
    print("3. 测试设备1的心跳，因为设备2的登录，设备1会掉线，设备1的tick会返回错误")
    tick_result = session.tick()
    assert not tick_result,"设备1应该返回失败"
    assert session.errorCode == keyi.ErrorCode.kTooManyDevice.value,"设备1应该返回错误码kTooManyDevice"
    print(f"设备1的心跳返回错误: {session.errorCode}，因为设备2的登录，设备1的session失效了")
    print("4. 设备2的心跳，返回正确")
    tick_result = session2.tick()
    assert tick_result,f"设备2的心跳返回错误: {session2.errorCode}"
    print(f"设备2的心跳返回正确: {session2.errorCode}")

    print("3. 注销设备1")
    logout_result = session2.logout()
    assert logout_result,f"注销失败: {session2.errorCode}"
    print("注销成功！")
    
  def test_device_limit2(self,keyCode:str):
    print("开始测试卡密的设备限制,在不同设备上登录，确保keyCode是只支持单设备登录的卡密")
    print("1. 登录设备1")
    session = keyi.Session(self.secretId,self.secretKey,self.projectId)
    login_result = session.login(keyCode,"device1")
    assert login_result,f"登录失败: {session.errorCode}"
    print("登录成功！")
    print("2. 登录设备2")
    session2 = keyi.Session(self.secretId,self.secretKey,self.projectId)
    login_result = session2.login(keyCode,"device2")
    assert login_result == False
    print("登录失败，因为keyCode只支持单设备登录")
    print("3. 注销设备1")
    logout_result = session.logout()
    assert logout_result,f"注销失败: {session.errorCode}"
    print("注销成功！")
    print("4. 登录设备2")
    login_result = session2.login(keyCode,"device2")
    assert login_result,f"登录失败: {session2.errorCode}"
    print("登录成功！")
    print("5. 注销设备2")
    logout_result = session2.logout()
    assert logout_result,f"注销失败: {session2.errorCode}"
    print("注销成功！")
    print("测试完成")
  
  def test_session_timeout(self,keyCode:str,machineId:str):
    print("开始测试卡密的会话超时，这个测试需要6分钟左右才能测试完成，请耐心等待")
    print("1. 登录设备")
    session = keyi.Session(self.secretId,self.secretKey,self.projectId)
    login_result = session.login(keyCode,machineId)
    assert login_result,f"登录失败: {session.errorCode}"
    print("登录成功！")
    print("2. 延迟6分钟")
    for i in range(36):
      print(f"还有 {(36-i)*10} 秒")
      time.sleep(10)
    print("3. 心跳")
    tick_result = session.tick()
    assert tick_result == False
    assert session.errorCode == keyi.ErrorCode.kInvalidSessionTokenOrKey.value
    print(f"心跳失败，因为会话超时,错误码: {session.errorCode}")
    print("因为会话超时，所以无需注销")
    print("测试完成")

  def test_suspended_keycard(self,keyCode:str,machineId:str):
    print("开始测试卡密的冻结，确保keyCode是冻结的卡密")
    print("1. 登录设备")
    session = keyi.Session(self.secretId,self.secretKey,self.projectId)
    login_result = session.login(keyCode,machineId)
    assert login_result == False
    assert session.errorCode == keyi.ErrorCode.kAccountSuspended.value
    print(f"登录失败，因为卡密被冻结,错误码: {session.errorCode}")
    print("测试完成")

  def test_suspend_keycard_on_running(self,keyCode:str,machineId:str):
    print("开始测试在运行时冻结卡密，确保keyCode是未冻结的卡密")
    print("1. 登录设备")
    session = keyi.Session(self.secretId,self.secretKey,self.projectId)
    login_result = session.login(keyCode,machineId)
    assert login_result,f"登录失败: {session.errorCode}"
    print("登录成功！")
    print("2. 冻结卡密，请您在管理后台操作，30秒后，会尝试心跳")
    time.sleep(30)
    print("3. 心跳")
    tick_result = session.tick()
    assert tick_result == False
    assert session.errorCode == keyi.ErrorCode.kAccountSuspended.value
    print(f"心跳失败，因为卡密被冻结,错误码: {session.errorCode}")
    print("4. 注销")
    logout_result = session.logout()
    assert logout_result,f"注销失败: {session.errorCode}"
    print("注销成功！")
    print("测试完成")

  def test_invalid_project_id(self,keyCode:str,machineId:str):
    print("开始测试卡密的软件ID错误")
    print("先尝试登录一下软件ID，确保登录成功")
    print("1. 登录设备")
    session = keyi.Session(self.secretId,self.secretKey,self.projectId)
    login_result = session.login(keyCode,machineId)
    assert login_result,f"登录失败: {session.errorCode}"
    print("登录成功！")
    print("2. 注销")
    logout_result = session.logout()
    assert logout_result,f"注销失败: {session.errorCode}"
    print("注销成功！")
    print("3. 修改软件ID")
    softwareId = self.projectId + 1
    print(f"3. 尝试登录软件ID: {softwareId}")
    session = keyi.Session(self.secretId,self.secretKey,softwareId)
    login_result = session.login(keyCode,machineId)
    assert login_result == False
    assert session.errorCode == keyi.ErrorCode.kInvalidProject.value
    print(f"登录失败，因为卡密绑定的软件ID错误,错误码: {session.errorCode}")
    print("测试完成")
  
  def test_too_many_requests(self,keyCode:str,machineId:str):
    print("开始测试卡密的请求过多，此测试完成后，请一段时间内不要再次测试，否则会被服务器拉黑")
    print("1. 登录设备")
    session = keyi.Session(self.secretId,self.secretKey,self.projectId)
    login_result = session.login(keyCode,machineId)
    assert login_result,f"登录失败: {session.errorCode}"
    print("登录成功！")
    print("2. 心跳")
    for i in range(100):
      tick_result = session.tick()
      if not tick_result:
        break
      time.sleep(1)
    assert session.errorCode == keyi.ErrorCode.kTooManyRequests.value
    print(f"心跳失败，因为请求过多,错误码: {session.errorCode}")
    print("3. 注销")
    logout_result = session.logout()
    assert logout_result,f"注销失败: {session.errorCode}"
    print("注销成功！")
    print("测试完成")

  # 测试云计算相关

  def test_cloud_variable(self,keyCode:str,machineId:str):
    print("开始测试云变量相关")
    print("1. 登录设备")
    session = keyi.Session(self.secretId,self.secretKey,self.projectId)
    login_result = session.login(keyCode,machineId)
    assert login_result,f"登录失败: {session.errorCode}"
    print("登录成功！")
    print("2. 检查云变量")
    name,age,qq = session.getValue("name","age","qq群")
    assert name == "李炙"
    assert age == 20
    assert qq == "481230042"
    print("检查云变量成功！")
    print("3. 修改云变量")
    assert session.setValue(name="荔枝",age=18,other="test")
    print("修改云变量成功！")
    print("4. 检查云变量")
    name,age,other = session.getValue("name","age","other")
    assert name == "荔枝"
    assert age == 18
    assert other == "test"
    print("检查云变量成功！")
    print("5. 注销")
    assert session.logout()
    print("注销成功！")
    print("测试完成")

  def test_cloud_method(self,keyCode:str,machineId:str):
    print("开始测试云方法相关")
    print("1. 登录设备")
    session = keyi.Session(self.secretId,self.secretKey,self.projectId)
    login_result = session.login(keyCode,machineId)
    assert login_result,f"登录失败: {session.errorCode}"
    print("登录成功！")
    print("2. 检查云方法")
    result = session.call("getEnv","name")
    assert result[0] == "李炙"
    session.call("setEnv","name","荔枝")
    result = session.call("getEnv","name")
    assert result[0] == "荔枝"
    x,y = session.call("scope",100,200)
    ox,oy = (100+50,200+50)
    assert x >= ox-20 and x <= ox+20
    assert y >= oy-20 and y <= oy+20
    print("检查云方法成功！")
    print("3. 注销")
    assert session.logout()
    print("注销成功！")
    print("测试完成")

  def test_cloud_config(self,keyCode:str,machineId:str):
    print("开始测试云配置相关")
    print("1. 登录设备")
    session = keyi.Session(self.secretId,self.secretKey,self.projectId)
    login_result = session.login(keyCode,machineId)
    assert login_result,f"登录失败: {session.errorCode}"
    print("登录成功！")
    print("2. 检查云配置")
    assert session.setConfig("荔枝")
    print("设置云配置成功！")
    assert session.getConfig() == "荔枝"
    print("检查云配置成功！")
    print("3. 注销")
    assert session.logout()
    print("注销成功！")
    print("测试完成")
    
  # 测试账号相关
  def test_register_account(self,email:str,password:str,nickname:str):
    print("开始测试注册账号")
    print("1. 注册账号")
    session = keyi.Session(self.secretId,self.secretKey,self.projectId)
    assert session.sendRegisterCode(email)
    print("发送注册码成功！")
    code = input("请输入验证码: ")
    assert session.registerAccount(email,password,nickname,int(code))
    print("注册账号成功！")

  def test_login_account(self,email:str,password:str,machineId:str):
    print("开始测试登录账号")
    print("1. 登录账号")
    session = keyi.Session(self.secretId,self.secretKey,self.projectId)
    assert session.login(email,machineId,password)
    print("登录账号成功！")
    assert session.logout()
    print("注销账号成功！")
    print("测试完成")
  
  def test_reset_password(self,email:str,password:str,machineId:str):
    print("开始测试重置密码")
    print("1. 登录账号")
    session = keyi.Session(self.secretId,self.secretKey,self.projectId)
    assert session.login(email,machineId,password)
    print("登录账号成功！")
    assert session.logout()
    print("注销账号成功！")
    print("2. 重置密码")
    print("发送验证码")
    assert session.sendResetPasswordCode(email)
    print("发送验证码成功！")
    code = input("请输入验证码: ")
    new_password = input("请输入新密码: ")
    assert session.resetPassword(email,new_password,int(code))
    print("重置密码成功！")
    print("使用旧密码登录")
    assert session.login(email,machineId,password) == False
    print("使用新密码登录")
    assert session.login(email,machineId,new_password)
    print("登录成功！")
    print("注销账号")
    assert session.logout()
    print("注销账号成功！")
    print("测试完成")

  def test_change_password(self,email:str,password:str,new_password:str,machineId:str):
    print("开始测试修改密码")
    print("1. 登录账号")
    session = keyi.Session(self.secretId,self.secretKey,self.projectId)
    assert session.login(email,machineId,password)
    print("登录账号成功！")
    assert session.logout()
    print("注销账号成功！")
    print("2. 修改密码")
    assert session.changePassword(email,password,new_password)
    print("修改密码成功！")
    print("3. 登录账号")
    assert session.login(email,machineId,new_password)
    print("登录账号成功！")
    print("注销账号")
    assert session.logout()
    print("注销账号成功！")
    print("测试完成")
